#!/usr/bin/python
# -*- coding: utf-8 -*-

import os
import sys
from time import gmtime, strftime
import gtk
import ConfigParser
import gettext
import mongoose

version = 1.0
  
class Log:
    def __init__(self):
        pass

    def read(self):
        pass
    
    def write(self):
        pass

class Config:
    def __init__(self):
        # Init defaults
        self.config_dir = os.path.expanduser("~/.config/poorguy/")
        self.config_file = self.config_dir + "config.cfg"
        
        self.server_root = os.path.expanduser("~/")
        self.server_start_page = "index.html"
        self.server_port = "8080"
        self.server_dir_listing = "no"
        self.server_max_conn = 30

        self.log_root =  os.path.expanduser("~/")
        self.console_log_file = self.log_root + "/poorguy-console.log"
        self.error_log_file = self.log_root + "/poorguy-error.log"
        self.log_to_console = "no"

        # Config parser
        self.parser = ConfigParser.RawConfigParser()
        
        # Check config
        self.check()
    
    def read(self):
        print("Read config...")

        self.parser.read(self.config_file)
        self.server_root = self.parser.get("SERVER", "root")
        self.server_start_page = self.parser.get("SERVER", "start_page")
        self.server_port = self.parser.get("SERVER", "port")
        self.server_dir_listing = self.parser.get("SERVER", "dir_listing")
        self.server_max_conn = self.parser.get("SERVER", "max_conn")

        self.log_root = self.parser.get("LOG", "root")
        self.log_to_console = self.parser.get("LOG", "log_to_console")
    
    def write(self):
        print("Write config...")

        if(self.parser.has_section("SERVER") == False):
            self.parser.add_section("SERVER")
        if(self.parser.has_section("LOG") == False):
            self.parser.add_section("LOG")
            
        self.parser.set("SERVER", "root", self.server_root)
        self.parser.set("SERVER", "start_page", self.server_start_page)
        self.parser.set("SERVER", "port", self.server_port)
        self.parser.set("SERVER", "dir_listing", self.server_dir_listing)
        self.parser.set("SERVER", "max_conn", self.server_max_conn)

        self.parser.set("LOG", "root", self.log_root)
        self.parser.set("LOG", "log_to_console", self.log_to_console)
        
        with open(self.config_file, "wb") as configfile:
            self.parser.write(configfile)
            configfile.close()

    def check(self):
        if(os.path.exists(self.config_dir) == False):
            print("Config directory was not found!")
            print("Config directory was created!")
            os.mkdir(self.config_dir)
        if(os.path.exists(self.config_file) == False):
            print("Config file was not foud!")
            print("Setup defaults!")
            
            self.write()

class WWWServer:
    def __init__(self, app, config):
        self.run = False
        self.config = config
        self.app = app
    
    def get_time(self):
        t = strftime("[%a, %d %b %Y %H:%M:%S] ", gmtime())
        return t

    def start_info(self):
        i = "Starting Mongoose %s on port(s) %s\n" % (self.server.version, self.server.ports)
        i += "CGI extensions: %s\n" % self.server.cgi_ext
        return i

    def start(self):
        if(self.run == False):
            self.server = mongoose.Mongoose()
            self.server.root = self.config.server_root
            self.server.ports = self.config.server_port
            self.server.dir_list = self.config.server_dir_listing
            self.server.max_threads = self.config.server_max_conn
            
            #self.server.set_uri_callback("/", self.uri_handler, 0)
            #self.server.set_error_callback(404, self.error_404_handler, 0)

            self.app.server_status_label.set_text("Running")
            self.app.server_root_label.set_text(self.config.server_root)
            self.app.text_buffer.insert(self.app.text_iter, self.start_info())
            self.app.text_buffer.insert(self.app.text_iter, self.get_time() + "Starting up... *done*\n")
            if(self.config.log_to_console == "no"):
                self.app.scroll_win.hide()
                self.app.window.resize(1,1)
            if(self.config.log_to_console == "yes"):
                self.app.scroll_win.show()
                self.app.window.resize(240, 320)
             
            self.run = True
    
    def stop(self):
        if(self.run == True):
            self.run = False
            self.app.server_status_label.set_text("Stopped")
            self.app.server_root_label.set_text(self.config.server_root)
            self.app.text_buffer.insert(self.app.text_iter, self.get_time() + "Shutting down.\n")
            if(self.config.log_to_console == "no"):
                self.app.scroll_win.hide()
                self.app.window.resize(1,1)
            if(self.config.log_to_console == "yes"):
                self.app.scroll_win.show()
                self.app.window.resize(240, 320)
            
            del self.server

    def uri_handler(self, conn, info, data):
        pass

    def error_404_handler(self):
        pass

class App:
    def __init__(self):
        self.in_tray = False
        
        self.builder = gtk.Builder()
        self.builder.add_from_file("gui.ui") 
        self.builder.connect_signals(self)

        # Get widgets
        self.window = self.builder.get_object("window")
        
        # Console
        self.text_buffer =  gtk.TextBuffer()
        self.text_iter = self.text_buffer.get_end_iter()
        self.console = self.builder.get_object("console")
        self.console.set_buffer(self.text_buffer)
        
        # Labels
        self.server_status_label = self.builder.get_object("server_status_label")
        self.server_root_label = self.builder.get_object("server_root_label")
        
        # Menu
        self.run_server_menu_item = self.builder.get_object("run_server_menu_item")

        # Scroll window
        self.scroll_win = self.builder.get_object("scroll_win")
        
        # Dialogs
        self.quit_dialog = self.builder.get_object("quit_dialog")
        self.about_dialog = self.builder.get_object("about_dialog")
        self.preferences_dialog = self.builder.get_object("preferences_dialog")

        # Preferences dialog
        self.web_dir_chooser = self.builder.get_object("web_dir_chooser")
        self.start_page_entry = self.builder.get_object("start_page_entry")
        self.port_spin_button  = self.builder.get_object("port_spin_button")
        self.dir_listing_cb = self.builder.get_object("dir_listing_cb")
        self.max_conn_scale = self.builder.get_object("max_conn_scale")

        self.log_dir_chooser = self.builder.get_object("log_dir_chooser")
        self.log_to_console_cb = self.builder.get_object("log_to_console_cb")
        
        # Tray menu
        self.tray_menu = self.builder.get_object("tray_menu")

        # Config
        self.config = Config()
        self.config.read()

        # Start server
        self.server = WWWServer(self, self.config)
        self.server.start()

        # Log
        self.log = Log()

        # Set server status to run_server_menu_item
        if(self.server.run == True):
            self.run_server_menu_item.set_active(True)
        else:
            self.run_server_menu_item.set_active(False)

    def on_quit(self, widget, data = None):
        print("Quit")
        self.server.stop()
        gtk.main_quit()

    def on_quit_dialog(self, widget, data = None):
        self.quit_dialog.run()
        self.quit_dialog.hide()
        
    def on_about_dialog(self, widget, data = None):
        self.about_dialog.run()
        self.about_dialog.hide()

    def on_save_preferences(self, widget, data = None):
        # Get values
        self.config.server_root = self.web_dir_chooser.get_filename()
        self.config.server_start_page = self.start_page_entry.get_text()
        self.config.server_port = int(self.port_spin_button.get_value())
        if(self.dir_listing_cb.get_active() == True):
            self.config.server_dir_listing = "yes"
        else:
            self.config.server_dir_listing = "no"
        self.config.server_max_conn = int(self.max_conn_scale.get_value())

        self.config.log_root = self.log_dir_chooser.get_filename()

        if(self.log_to_console_cb.get_active() == True):
            self.config.log_to_console = "yes"
        else:
            self.config.log_to_console = "no"

        self.config.write()

    def on_preferences_dialog(self, widget, data = None):
        self.config.read()
        # Set values
        self.web_dir_chooser.set_filename(self.config.server_root)
        self.start_page_entry.set_text(self.config.server_start_page)
        self.port_spin_button.set_value(float(self.config.server_port))
        if(self.config.server_dir_listing == "yes"):
            self.dir_listing_cb.set_active(True)
        if(self.config.server_dir_listing == "no"):
            self.dir_listing_cb.set_active(False)
        self.max_conn_scale.set_value(float(self.config.server_max_conn))

        self.log_dir_chooser.set_filename(self.config.log_root)
        if(self.config.log_to_console == "yes"):
            self.log_to_console_cb.set_active(True)
        if(self.config.log_to_console == "no"):
            self.log_to_console_cb.set_active(False)

        self.preferences_dialog.run()
        self.preferences_dialog.hide()

    def on_popup_tray(self, tray, button, time):
        self.tray_menu.popup(None, None, None, button, time, tray)

    def on_hide_tray(self, widget, data = None):
        if(self.in_tray == False):
            self.window.hide()
            self.in_tray = True
        else:
            self.window.show()
            self.in_tray = False
        
        return True
    
    def on_run_server(self, widget, data = None):
        check = self.run_server_menu_item.get_active()
        
        if(check == True):
            self.server.start()
        else:
            self.server.stop()
            
if __name__ == "__main__":
    if sys.argv.count("--version"):
        print "poorguy-" + str(version)

    else:
        app = App()
        app.window.show()
        gtk.main()



